﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Windows.Forms;

namespace MagicCove
{
    public partial class GameForm : Form //note this has been change to internal as otherwise stack could not be accessed (can only be accessed by things assembled with it) ???
    {
        #region Variables
        private Player loser;
        private bool enforceRules;//if the game should take care of enforcing the rules. this will not be changed while the gameform is running
        private MagicField p1Field;
        private MagicField p2Field;
        private Player turn; //true if p1 turn, false if p2turn
        private Player priority; //true if p1 has priority, false if p2 has priority
        private int numberOfPlayers;
        private int stackCountPrio; //has the previous stack length to see if the stack has changed since last time
        private Phase phase; //current phase of the game 0-Untap Step, 1-Upkeep Step, 2-Draw Step, 3-First Main Step, 4-Beginning of Combat, 5-Declare Attackers, 6-Declare Blockers, 7-Combat Damage, 8-End of Combat, 9-Second Main Step, 10-End Step, 11-Clean Up Step
        private List<MagicCard> currentTargets; //hold a list of the targets that are considered the current target. Updated everytime the select targets is pressed
        private List<MagicCard> attackingCreatures;
        private List<MagicCard> defendingCreatures;
        private List<PictureBox> p1HandPBs; //holds the picture boxes for player ones hand
        private List<PictureBox> p2HandPBs; //hold the picture boxes for player twos hand
        private List<PictureBox> p1FieldPBs; //holds the picture boxes for player 1 field
        private List<PictureBox> p2FieldPBs; //holds the picture boxes for player 2's field
        private Hashtable cardImages;

        internal Stack<MagicStackItem> stack;//the game stack, cleared when stack fully resolved
        #endregion

        public GameForm(String p1Deck, String p2Deck, bool enforceRules)
        {
            InitializeComponent();
            CustomizeComponents();
            this.enforceRules = enforceRules;
            if (!enforceRules)
                CustomizeComponentsForNoRules();
            stack = new Stack<MagicStackItem>();
            currentTargets = new List<MagicCard>();
            attackingCreatures = new List<MagicCard>();
            defendingCreatures = new List<MagicCard>();
            stackCountPrio = -1;
            loser = Player.None; //no one has lost, will have number of player that lost
            turn = Player.P1; //for now later this may change based on selection ~!~
            priority = Player.P1;
            numberOfPlayers = 2; //for now
            updateTurnLabel();
            phase = Phase.PreCombatMain;
            gamePhaseL.Text = "First Main Step";
            currentMessageL.Text = "Start the game or right click for the menu. Enjoy!";
            p1Field = new MagicField(GameFunctions.stripDeck(p1Deck), Player.P1, this, enforceRules);
            p2Field = new MagicField(GameFunctions.stripDeck(p2Deck), Player.P2, this, enforceRules);
            cardImages = new Hashtable();
            initializeCardBitmapHT();
            initializePBLists();
            updateHandWithCardBacks(1);//so cards are intially displayed with there backs and not revealed
            updateHandWithCardBacks(2);
            activateAllSE();
            updateGame();
        }
        #region Initialization Functions
        private void initializePBLists()
        {
            p1HandPBs = new List<PictureBox> { 
                p1Hand0PB, 
                p1Hand1PB, 
                p1Hand2PB, 
                p1Hand3PB, 
                p1Hand4PB, 
                p1Hand5PB, 
                p1Hand6PB, 
                p1Hand7PB, 
                p1Hand8PB, 
                p1Hand9PB };
            p2HandPBs = new List<PictureBox> { 
                p2Hand0PB, 
                p2Hand1PB, 
                p2Hand2PB, 
                p2Hand3PB, 
                p2Hand4PB, 
                p2Hand5PB, 
                p2Hand6PB, 
                p2Hand7PB, 
                p2Hand8PB, 
                p2Hand9PB };
            p1FieldPBs = new List<PictureBox>();
            p2FieldPBs = new List<PictureBox>();
        }
        private Form pBForm;
        private ProgressBar cardLoadingPB;
        private void initializeCardBitmapHT()
        {
            pBForm = new Form();
            pBForm.ControlBox = false;
            pBForm.Text = "Downloading Card Images: 0%";
            pBForm.Size = new System.Drawing.Size(306, 170);
            pBForm.StartPosition = FormStartPosition.CenterParent;
            cardLoadingPB = new ProgressBar();
            cardLoadingPB.Location = new Point(0, 100);
            cardLoadingPB.Size = new System.Drawing.Size(306, 70);
            cardLoadingPB.Minimum = 0;
            cardLoadingPB.Maximum = 100;
            cardLoadingPB.Value = 0;
            pBForm.Controls.Add(cardLoadingPB);
            Label informationLabel = new Label();
            informationLabel.Size = new System.Drawing.Size(306, 100);
            informationLabel.Text = "If you have cards in your deck you have not previously used, they may take a while to download. Please be patient.\n(We need to download each individual card for copyright reasons. However we only need to do this once.)\n\n\nDownload in progress...";
            pBForm.Controls.Add(informationLabel);

            BackgroundWorker pBBW = new BackgroundWorker();
            pBBW.DoWork += new DoWorkEventHandler(cardImagesBW_DoWork);
            pBBW.RunWorkerCompleted += new RunWorkerCompletedEventHandler(cardImagesBW_RunWorkerCompleted);
            pBBW.ProgressChanged += new ProgressChangedEventHandler(cardImagesBW_ProgressChanged);
            pBBW.WorkerReportsProgress = true;
            pBBW.RunWorkerAsync();
            pBForm.ShowDialog();
        }
        private void putAllCardImagesInHash(BackgroundWorker worker)
        {
            int highestReportedPercentage = 0;
            int totalTokens = 32;
            int totalCards = p1Field.deck.Count + p2Field.deck.Count + p1Field.hand.Count + p2Field.hand.Count + totalTokens;
            int cardCounter = 0;
            foreach (MagicCard mc in p1Field.deck)
            {
                cardCounter++;
                // Report progress as a percentage of the total task.
                if ((cardCounter * 100 / totalCards) > highestReportedPercentage)
                {
                    highestReportedPercentage = cardCounter * 100 / totalCards;
                    worker.ReportProgress(highestReportedPercentage);
                }
                try
                {//throws exception if element is already in the hash table, should no longer throw exeption
                    if(!cardImages.ContainsKey(mc.CardName))
                        cardImages.Add(mc.CardName, GameFunctions.getCardImage(mc.CardName));
                }
                catch { }
            }
            foreach (MagicCard mc in p1Field.hand)
            {
                cardCounter++;
                // Report progress as a percentage of the total task.
                if ((cardCounter * 100 / totalCards) > highestReportedPercentage)
                {
                    highestReportedPercentage = cardCounter * 100 / totalCards;
                    worker.ReportProgress(highestReportedPercentage);
                }
                try
                {//throws exception if element is already in the hash table, should no longer throw exeption
                    if (!cardImages.ContainsKey(mc.CardName))
                        cardImages.Add(mc.CardName, GameFunctions.getCardImage(mc.CardName));
                }
                catch { }
            }
            foreach (MagicCard mc in p2Field.deck)
            {
                cardCounter++;
                // Report progress as a percentage of the total task.
                if ((cardCounter * 100 / totalCards) > highestReportedPercentage)
                {
                    highestReportedPercentage = cardCounter * 100 / totalCards;
                    worker.ReportProgress(highestReportedPercentage);
                }
                try
                {//throws exception if element is already in the hash table, should no longer throw exeption
                    if(!cardImages.ContainsKey(mc.CardName))
                        cardImages.Add(mc.CardName, GameFunctions.getCardImage(mc.CardName));
                }
                catch { }
            }
            foreach (MagicCard mc in p2Field.hand)
            {
                cardCounter++;
                // Report progress as a percentage of the total task.
                if ((cardCounter * 100 / totalCards) > highestReportedPercentage)
                {
                    highestReportedPercentage = cardCounter * 100 / totalCards;
                    worker.ReportProgress(highestReportedPercentage);
                }
                try
                {//throws exception if element is already in the hash table, should no longer throw exeption
                    if(!cardImages.ContainsKey(mc.CardName))
                        cardImages.Add(mc.CardName, GameFunctions.getCardImage(mc.CardName));
                }
                catch { }
            }
            for (int i = 0; i < totalTokens; i++)//could also do a while not returning null
            {
                cardCounter++;
                // Report progress as a percentage of the total task.
                if ((cardCounter * 100 / totalCards) > highestReportedPercentage)
                {
                    highestReportedPercentage = cardCounter * 100 / totalCards;
                    worker.ReportProgress(highestReportedPercentage);
                }
                try
                {//throws exception if element is already in the hash table
                    cardImages.Add(CardDefLibrary.getTokenStringByNumber(i), GameFunctions.getTokenImage(CardDefLibrary.getTokenStringByNumber(i), CardDefLibrary.getTokenImageURLByNumber(i)));
                }
                catch { }
            }
        }
        private void cardImagesBW_DoWork(object sender, DoWorkEventArgs e)
        {
            // Get the BackgroundWorker that raised this event.
            BackgroundWorker worker = sender as BackgroundWorker;

            // Assign the result of the computation
            // to the Result property of the DoWorkEventArgs
            // object. This is will be available to the 
            // RunWorkerCompleted eventhandler.
            putAllCardImagesInHash(worker);
        }
        // This event handler updates the progress bar.
        private void cardImagesBW_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.pBForm.Text = "Downloading Card Images: " + e.ProgressPercentage + "%";
            this.cardLoadingPB.Value = e.ProgressPercentage;
        }
        private void cardImagesBW_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            pBForm.Close();
            pBForm.Dispose();
        }
        #endregion
        #region Get Variables
        internal List<MagicCard> AttackingCreatures
        {
            get
            {
                return this.attackingCreatures;
            }
        }
        internal List<MagicCard> DefendingCreatures
        {
            get
            {
                return this.defendingCreatures;
            }
        }
        internal Phase CurrentPhase
        {
            get
            {
                return phase;
            }
        }
        internal Player Turn
        {
            get
            {
                return turn;
            }
        }
        internal Player Priority
        {
            get
            {
                return priority;
            }
        }
        #endregion
        #region General Functions
        private Image getCardImage(MagicCard card)
        {//returns a clone of the image (so if it manipulated it won't effect all of them). Important for tapping a card
            return (Image)((Image) cardImages[card.CardName]).Clone();
        }
        private List<MagicCard> getAllSelectedCardsWithoutStack()
        {//this function could be made more efficient. select index is assumed to be constant given no listbox change, though randomely one of selectedIndices
            List<MagicCard> cardsSelected = new List<MagicCard>();
            int tempTotalSelected = 0;
            tempTotalSelected += p1HandLB.SelectedIndices.Count;
            tempTotalSelected += p2HandLB.SelectedIndices.Count;
            tempTotalSelected += p1FieldLB.SelectedIndices.Count;
            tempTotalSelected += p2FieldLB.SelectedIndices.Count;
            tempTotalSelected += p1GraveyardLB.SelectedIndices.Count;
            tempTotalSelected += p2GraveyardLB.SelectedIndices.Count;
            tempTotalSelected += p1ExiledLB.SelectedIndices.Count;
            tempTotalSelected += p2ExiledLB.SelectedIndices.Count;
            while (tempTotalSelected > 0)
            {
                if (p1HandLB.SelectedIndices.Count != 0)
                {
                    cardsSelected.Add(p1Field.hand[p1HandLB.SelectedIndex]);
                    p1HandLB.SetSelected(p1HandLB.SelectedIndex, false);
                }
                if (p2HandLB.SelectedIndices.Count != 0)
                {
                    cardsSelected.Add(p2Field.hand[p2HandLB.SelectedIndex]);
                    p2HandLB.SetSelected(p2HandLB.SelectedIndex, false);
                }
                if (p1FieldLB.SelectedIndices.Count != 0)
                {
                    cardsSelected.Add(p1Field.field[p1FieldLB.SelectedIndex]);
                    p1FieldLB.SetSelected(p1FieldLB.SelectedIndex, false);
                }
                if (p2FieldLB.SelectedIndices.Count != 0)
                {
                    cardsSelected.Add(p2Field.field[p2FieldLB.SelectedIndex]);
                    p2FieldLB.SetSelected(p2FieldLB.SelectedIndex, false);
                }
                if (p1GraveyardLB.SelectedIndices.Count != 0)
                {
                    cardsSelected.Add(p1Field.graveyard[p1GraveyardLB.SelectedIndex]);
                    p1GraveyardLB.SetSelected(p1GraveyardLB.SelectedIndex, false);
                }
                if (p2GraveyardLB.SelectedIndices.Count != 0)
                {
                    cardsSelected.Add(p2Field.graveyard[p2GraveyardLB.SelectedIndex]);
                    p2GraveyardLB.SetSelected(p2GraveyardLB.SelectedIndex, false);
                }
                if (p1ExiledLB.SelectedIndices.Count != 0)
                {
                    cardsSelected.Add(p1Field.exiled[p1ExiledLB.SelectedIndex]);
                    p1ExiledLB.SetSelected(p1ExiledLB.SelectedIndex, false);
                }
                if (p2ExiledLB.SelectedIndices.Count != 0)
                {
                    cardsSelected.Add(p2Field.exiled[p2ExiledLB.SelectedIndex]);
                    p2ExiledLB.SetSelected(p2ExiledLB.SelectedIndex, false);
                }
                tempTotalSelected = 0;
                tempTotalSelected += p1HandLB.SelectedIndices.Count;
                tempTotalSelected += p2HandLB.SelectedIndices.Count;
                tempTotalSelected += p1FieldLB.SelectedIndices.Count;
                tempTotalSelected += p2FieldLB.SelectedIndices.Count;
                tempTotalSelected += p1GraveyardLB.SelectedIndices.Count;
                tempTotalSelected += p2GraveyardLB.SelectedIndices.Count;
                tempTotalSelected += p1ExiledLB.SelectedIndices.Count;
                tempTotalSelected += p2ExiledLB.SelectedIndices.Count;
            }
            return cardsSelected;
        }
        private List<MagicCard> getAllSelectedCardsWithStack() 
        {
            List<MagicCard> retVal = getAllSelectedCardsWithoutStack();
            MagicStackItem[] tempArray = stack.ToArray();
            foreach (int i in stackLB.SelectedIndices)
                retVal.Add((MagicCard)tempArray[i]);
            stackLB.ClearSelected();
            return retVal;
        }
        private void clearAllSelectedCard()
        {//clears the selection in all list boxes
            p1HandLB.ClearSelected();
            p2HandLB.ClearSelected();
            p1FieldLB.ClearSelected();
            p2FieldLB.ClearSelected();
            p1GraveyardLB.ClearSelected();
            p2GraveyardLB.ClearSelected();
            p1ExiledLB.ClearSelected();
            p2ExiledLB.ClearSelected();
        }
        private void moveAllCards()
        {//first check a card needs to be moved before moving it, this permits the cards that do not need to be moved to stay in the same location.
            //may need to consider deck, depending on how we want some of the sE to work

            /*                 if (mCD.TempDefense <= 0)
                    mCD.LocationGoing = CurrentLocation.Graveyard;
                if (mCD.combatTarget[0].TempDefense <= 0)
                    mCD.combatTarget[0].LocationGoing = CurrentLocation.Graveyard; 
             * Need to add something similar to above before moving the cards to send all dead creatures to the graveyard ~!~*/

            //~!~ need to move the deck also
            for (int i = 0; i < p1Field.hand.Count; i++)
                if (p1Field.hand[i].Location != p1Field.hand[i].LocationGoing)
                {
                    moveCard(p1Field.hand[i]);
                    i--;//as the card will be removed from the current list, everything else will be shifted down so the next element in the list is actually the current i.
                }
            for (int i = 0; i < p2Field.hand.Count; i++)
                if (p2Field.hand[i].Location != p2Field.hand[i].LocationGoing)
                {
                    moveCard(p2Field.hand[i]);
                    i--;//as the card will be removed from the current list, everything else will be shifted down so the next element in the list is actually the current i.
                }
            if (enforceRules)//move just the top ones that need to me move
                while (stack.Count > 0 && stack.Peek().GetType().Equals(typeof(MagicCard)) && ((MagicCard)stack.Peek()).Location != ((MagicCard)stack.Peek()).LocationGoing)
                    moveCard((MagicCard)stack.Peek());
            else //move everything on the stack that needs movement, cannot just rely on move card as it only works for the top element of the stack. what we can do however is rearange the stack so the top elements are the ones to be move
            {//everything is assumed to be a magic card in this mode of play for now
                List<MagicStackItem> tempL = stack.ToList<MagicStackItem>();
                for (int i = 0; i < tempL.Count; i++)//note order of the items coming off will be reversed
                {
                    if (((MagicCard)tempL[i]).LocationGoing != ((MagicCard)tempL[i]).Location)
                    {
                        tempL.Insert(0, tempL[i]);
                        tempL.RemoveAt(i + 1);
                    }
                }
                stack = new Stack<MagicStackItem>(tempL);
                while (stack.Count > 0 && ((MagicCard)stack.Peek()).Location != ((MagicCard)stack.Peek()).LocationGoing)
                    moveCard((MagicCard)stack.Peek());
            }
            for (int i = 0; i < p1Field.field.Count; i++)
                if (p1Field.field[i].Location != p1Field.field[i].LocationGoing)
                {
                    moveCard(p1Field.field[i]);
                    i--;//as the card will be removed from the current list, everything else will be shifted down so the next element in the list is actually the current i.
                }
            for (int i = 0; i < p2Field.field.Count; i++)
                if (p2Field.field[i].Location != p2Field.field[i].LocationGoing)
                {
                    moveCard(p2Field.field[i]);
                    i--;//as the card will be removed from the current list, everything else will be shifted down so the next element in the list is actually the current i.
                }
            for (int i = 0; i < p1Field.graveyard.Count; i++)
                if (p1Field.graveyard[i].Location != p1Field.graveyard[i].LocationGoing)
                {
                    moveCard(p1Field.graveyard[i]);
                    i--;//as the card will be removed from the current list, everything else will be shifted down so the next element in the list is actually the current i.
                }
            for (int i = 0; i < p2Field.graveyard.Count; i++)
                if (p2Field.graveyard[i].Location != p2Field.graveyard[i].LocationGoing)
                {
                    moveCard(p2Field.graveyard[i]);
                    i--;//as the card will be removed from the current list, everything else will be shifted down so the next element in the list is actually the current i.
                }
            for (int i = 0; i < p1Field.exiled.Count; i++)
                if (p1Field.exiled[i].Location != p1Field.exiled[i].LocationGoing)
                {
                    moveCard(p1Field.exiled[i]);
                    i--;//as the card will be removed from the current list, everything else will be shifted down so the next element in the list is actually the current i.
                }
            for (int i = 0; i < p2Field.exiled.Count; i++)
                if (p2Field.exiled[i].Location != p2Field.exiled[i].LocationGoing)
                {
                    moveCard(p2Field.exiled[i]);
                    i--;//as the card will be removed from the current list, everything else will be shifted down so the next element in the list is actually the current i.
                }
        }
        internal void moveCard(MagicCard card)
        {//Remove Card from it current location
            switch (card.Location)
            {
                case CurrentLocation.Deck:
                    break; //don't do anything, this case will be handled by its special effect as it has determine where in the deck it goes
                //note the card will automatically be removed from the top of the stack
                case CurrentLocation.Hand:
                    if (card.Owner == Player.P1)
                        p1Field.hand.Remove(card);
                    else
                        p2Field.hand.Remove(card);
                    break;
                case CurrentLocation.Stack://the card if it is being removed is at the top of the stack
                    stack.Pop();
                    break;
                case CurrentLocation.Field: //also handle gui display
                    if (card.Owner == Player.P1)
                    {
                        PictureBox pB = p1FieldPBs[p1Field.field.IndexOf(card)];
                        p1FieldPBs.Remove(pB);
                        pB.Dispose();
                        p1Field.field.Remove(card);
                    }
                    else
                    {
                        PictureBox pB = p2FieldPBs[p2Field.field.IndexOf(card)];
                        p2FieldPBs.Remove(pB);
                        pB.Dispose();
                        p2Field.field.Remove(card);
                    }
                    break;
                case CurrentLocation.Graveyard:
                    if (card.Owner == Player.P1)
                        p1Field.graveyard.Remove(card);
                    else
                        p2Field.graveyard.Remove(card);
                    break;
                case CurrentLocation.Exiled:
                    if (card.Owner == Player.P1)
                        p1Field.exiled.Remove(card);
                    else
                        p2Field.exiled.Remove(card);
                    break;
                default:
                    MessageBox.Show("An error occured in moveCard()-R.");
                    break;
            }
            //Add card to location going
            switch (card.LocationGoing)
            {
                case CurrentLocation.Deck:
                    break; //don't do anything, this case will be handled by its special effect as it has determine where in the deck it goes
                //note the card will automatically be removed from the top of the stack
                case CurrentLocation.Hand:
                    if (card.Owner == Player.P1)
                        p1Field.hand.Add(card);
                    else
                        p2Field.hand.Add(card);
                    break;
                case CurrentLocation.Stack://the card if it is being removed is at the top of the stack
                    stack.Push(card);
                    break;
                case CurrentLocation.Field:
                    if (card.Owner == Player.P1)
                    {
                        PictureBox tempPB = new PictureBox();
                        tempPB.Name = "p1FieldPB" + p1FieldPBs.Count.ToString();
                        tempPB.Size = new System.Drawing.Size(75, 104);
                        tempPB.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
                        tempPB.Image = getCardImage(card);
                        tempPB.Location = new System.Drawing.Point(p1FieldPBs.Count * 12, p1FieldPBs.Count * 12);
                        tempPB.ContextMenuStrip = this.cardCMS;
                        tempPB.MouseEnter += new System.EventHandler(this.p1FieldPB_MouseEnter);
                        tempPB.MouseLeave += new System.EventHandler(this.p1FieldPB_MouseLeave);
                        tempPB.MouseDown += new MouseEventHandler(GUIPBDrag_MouseDown);
                        tempPB.MouseUp += new MouseEventHandler(GUIPBDrag_MouseUp);
                        tempPB.MouseMove += new MouseEventHandler(GUIPBDrag_MouseMove);
                        tempPB.MouseDoubleClick += new MouseEventHandler(fieldPB_MouseDoubleClick);
                        p1FieldGUI19SC.Panel2.Controls.Add(tempPB);
                        tempPB.BringToFront();
                        p1FieldPBs.Add(tempPB);
                        p1Field.field.Add(card);
                    }
                    else
                    {
                        PictureBox tempPB = new PictureBox();
                        tempPB.Name = "p2FieldPB" + p2FieldPBs.Count.ToString();
                        tempPB.Size = new System.Drawing.Size(75, 104);
                        tempPB.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
                        tempPB.Image = getCardImage(card);
                        tempPB.Location = new System.Drawing.Point(p2FieldPBs.Count * 12, p2FieldGUI18SC.Panel1.ClientSize.Height - tempPB.Size.Height - p2FieldPBs.Count * 12);
                        tempPB.ContextMenuStrip = this.cardCMS;
                        tempPB.MouseEnter += new System.EventHandler(this.p2FieldPB_MouseEnter);
                        tempPB.MouseLeave += new System.EventHandler(this.p2FieldPB_MouseLeave);
                        tempPB.MouseDown += new MouseEventHandler(GUIPBDrag_MouseDown);
                        tempPB.MouseUp += new MouseEventHandler(GUIPBDrag_MouseUp);
                        tempPB.MouseMove += new MouseEventHandler(GUIPBDrag_MouseMove);
                        tempPB.MouseDoubleClick += new MouseEventHandler(fieldPB_MouseDoubleClick);
                        p2FieldGUI18SC.Panel1.Controls.Add(tempPB);
                        tempPB.BringToFront();
                        p2FieldPBs.Add(tempPB);
                        p2Field.field.Add(card);
                    }
                    break;
                case CurrentLocation.Graveyard:
                    if (card.Owner == Player.P1)
                        p1Field.graveyard.Add(card);
                    else
                        p2Field.graveyard.Add(card);
                    break;
                case CurrentLocation.Exiled:
                    if (card.Owner == Player.P1)
                        p1Field.exiled.Add(card);
                    else
                        p2Field.exiled.Add(card);
                    break;
                default:
                    MessageBox.Show("An error occured in moveCard()-A.");
                    break;
            }

            card.Location = card.LocationGoing;
        }
        internal void moveCardToDeck(MagicCard card, bool topOfDeck, bool shuffleDeck)
        {
            switch (card.Location)
            {
                case CurrentLocation.Hand:
                    if (card.Owner == Player.P1)
                        p1Field.hand.Remove(card);
                    else
                        p2Field.hand.Remove(card);
                    break;
                case CurrentLocation.Stack://the card if it is being removed is at the top of the stack
                    stack.Pop();
                    break;
                case CurrentLocation.Field:
                    if (card.Owner == Player.P1)
                        p1Field.field.Remove(card);
                    else
                        p2Field.field.Remove(card);
                    break;
                case CurrentLocation.Graveyard:
                    if (card.Owner == Player.P1)
                        p1Field.graveyard.Remove(card);
                    else
                        p2Field.graveyard.Remove(card);
                    break;
                case CurrentLocation.Exiled:
                    if (card.Owner == Player.P1)
                        p1Field.exiled.Remove(card);
                    else
                        p2Field.exiled.Remove(card);
                    break;
                default:
                    MessageBox.Show("An error occured in moveCardToDeck()-R.");
                    break;
            }
            //Add card to location going
            if (!topOfDeck)
                card.ParentField.addToDeckBottom(card);
            else
                card.ParentField.addToDeck(0, card);
            if (shuffleDeck)
                card.ParentField.shuffleDeck();
            card.Location = card.LocationGoing;
        }
        private void performCombat()
        {//performs the combat ~!~ (currently in a very rudementary form)
            //assumes 1v1 combat, see note in updatePhase function
            foreach (MagicCard mCD in defendingCreatures)
            {
                //perform an individual fight, assumes that all defending creatures have been properly set to defend a creature. (Otherwise what is it doing in the list???)
                //we need some way to handle first strike, double strike and the like ~!~
                //also need to firmly decide how TempAttack and attack differ. i think Attack will be readonly, and temp will allow other sE to modify. At end of turn temp set to Non-temp value
                mCD.TempDefense -= mCD.combatTarget.TempAttack;
                mCD.combatTarget.TempDefense -= mCD.TempAttack;
                attackingCreatures.Remove(mCD.combatTarget);
            }
            foreach (MagicCard mCA in attackingCreatures) //the remaining attacking creatures, ie the ones that got through
            {
                if (turn == Player.P1)
                    p2Field.life -= mCA.TempAttack;
                else
                    p1Field.life -= mCA.TempAttack;
            }
        }
        private void resetAllCreaturesAttackAndDefense()
        {//sets temp attack and temp defense back to normal
            foreach (MagicCard card in p1Field.hand)
            {
                card.TempAttack = card.Attack;
                card.TempDefense = card.Defense;
            }
            foreach (MagicCard card in p2Field.hand)
            {
                card.TempAttack = card.Attack;
                card.TempDefense = card.Defense;
            }
            foreach (MagicCard card in p1Field.field)
            {
                card.TempAttack = card.Attack;
                card.TempDefense = card.Defense;
            }
            foreach (MagicCard card in p2Field.field)
            {
                card.TempAttack = card.Attack;
                card.TempDefense = card.Defense;
            }
            foreach (MagicCard card in p1Field.graveyard)
            {
                card.TempAttack = card.Attack;
                card.TempDefense = card.Defense;
            }
            foreach (MagicCard card in p2Field.graveyard)
            {
                card.TempAttack = card.Attack;
                card.TempDefense = card.Defense;
            }
            foreach (MagicCard card in p1Field.exiled)
            {
                card.TempAttack = card.Attack;
                card.TempDefense = card.Defense;
            }
            foreach (MagicCard card in p2Field.exiled)
            {
                card.TempAttack = card.Attack;
                card.TempDefense = card.Defense;
            }
        }
        private MagicField getCardsField(MagicCard mC)
        {//returns the field the magic card is on. right now it is just based on the owner, but if this is not the case
            //once cards can be stolen from their owner, and go to another field. however for now it will do ~!~
            if (mC.Owner == Player.P1)
                return p1Field;
            else
                return p2Field;
        }
        private MagicField getOponentsField(MagicCard mC)
        {//similar to above ~!~
            if (mC.Owner == Player.P1)
                return p2Field;
            else
                return p1Field;
        }
        #endregion
        #region Update Functions
        private void updateGame()
        {//updates the displays to reflect the current status of the game
            moveAllCards();
            updateAllDisplays();
            if (enforceRules)
                updateStats();
            if (loser == Player.P1 || p1Field.life <= 0 || p1Field.PoisonCounters >= 10) //checks if someone lost the game
                MessageBox.Show("Player 1 Lost the Game");
            else if (loser == Player.P1 || p2Field.life <= 0 || p1Field.PoisonCounters >= 10)
                MessageBox.Show("Player 2 Lost the Game");
        }
        private void updateStats()
        {//updates life and other game statistics that may be added
            updateLife();
            updateMana();
        }
        private void updateHand(int player)
        {
            if (player == 1)
                if (p1HandLB.FindStringExact("Card 1") == -1) //then it is being shown
                    updateHandWithCardImages(1);
                else
                    updateHandWithCardBacks(1);
            if (player == 2)
                if (p2HandLB.FindStringExact("Card 1") == -1) //then it is being shown
                    updateHandWithCardImages(2);
                else
                    updateHandWithCardBacks(2);
            //don't display if less than or equal to 10
            if (p1Field.hand.Count <= p1HandPBs.Count)
                p1CardsNotInHandL.Visible = false;
            else
            {
                p1CardsNotInHandL.Visible = true;
                p1CardsNotInHandL.Text = (p1Field.hand.Count - p1HandPBs.Count).ToString() + "\nCards\nNot\nShown";
            }
            if (p2Field.hand.Count <= p2HandPBs.Count)
                p2CardsNotInHandL.Visible = false;
            else
            {
                p2CardsNotInHandL.Visible = true;
                p2CardsNotInHandL.Text = (p2Field.hand.Count - p2HandPBs.Count).ToString() + "\nCards\nNot\nShown";
            }
        }
        private void updateHandWithCardImages(int player) //has which player to update, should take 1 or 2, updates showing cards
        {
            if (player == 1)
            {
                p1HandLB.Items.Clear();
                for (int i = 0; i < p1Field.hand.Count; i++)
                {
                    if (p1Field.hand[i] == null)//game over cause player one drew a null card
                    {
                        loser = Player.P1;
                        return;
                    }
                    else
                    {
                        p1HandLB.Items.Add(p1Field.hand[i].CardName);
                        if (i < p1HandPBs.Count) //in case they drew a bunch of cards make sure the cards can be displayed
                        {
                            p1HandPBs[i].Image = getCardImage(p1Field.hand[i]);
                            p1HandPBs[i].Visible = true;
                        }
                    }
                }
                for (int i = p1Field.hand.Count; i < p1HandPBs.Count; i++)
                {
                    p1HandPBs[i].Visible = false;
                }
            }
            else if (player == 2)
            {
                p2HandLB.Items.Clear();
                for (int i = 0; i < p2Field.hand.Count; i++)
                {
                    if (p2Field.hand[i] == null)//game over cause player one drew a null card
                    {
                        loser = Player.P1;
                        return;
                    }
                    else
                    {
                        p2HandLB.Items.Add(p2Field.hand[i].CardName);
                        if (i < p1HandPBs.Count) //in case they drew a bunch of cards make sure the cards can be displayed
                        {
                            p2HandPBs[i].Image = getCardImage(p2Field.hand[i]);
                            p2HandPBs[i].Visible = true;
                        }
                    }
                }
                for (int i = p2Field.hand.Count; i < p2HandPBs.Count; i++)
                {
                    p2HandPBs[i].Visible = false;
                }
            }
        }
        private void updateHandWithCardBacks(int player) //has which player to update, should take 1 or 2, updates blank hand (just seeing how many cards)
        {
            if (player == 1)
            {
                p1HandLB.Items.Clear();
                for (int i = 0; i < p1Field.hand.Count; i++)
                {
                    if (p1Field.hand[i] == null)//game over cause player one drew a null card
                    {
                        loser = Player.P1;
                        return;
                    }
                    else
                    {
                        p1HandLB.Items.Add("Card " + (i - (-1)));
                        if (i < p1HandPBs.Count) //in case they drew a bunch of cards make sure the cards can be displayed
                        {
                            p1HandPBs[i].Image = MagicCove.Properties.Resources.magicCardBackSized;
                            p1HandPBs[i].Visible = true;
                        }
                    }
                }
                for (int i = p1Field.hand.Count; i < p1HandPBs.Count; i++)
                {
                    p1HandPBs[i].Visible = false;
                }
            }
            else if (player == 2)
            {
                p2HandLB.Items.Clear();
                for (int i = 0; i < p2Field.hand.Count; i++)
                {
                    if (p2Field.hand[i] == null)//game over cause player one drew a null card
                    {
                        loser = Player.P2;
                        return;
                    }
                    else
                    {
                        p2HandLB.Items.Add("Card " + (i - (-1)));
                        if (i < p2HandPBs.Count) //in case they drew a bunch of cards make sure the cards can be displayed
                        {
                            p2HandPBs[i].Image = MagicCove.Properties.Resources.magicCardBackSized;
                            p2HandPBs[i].Visible = true;
                        }
                    }
                }
                for (int i = p2Field.hand.Count; i < p2HandPBs.Count; i++)
                {
                    p2HandPBs[i].Visible = false;
                }
            }
        }
        private void updateStack()
        {
            stackLB.Items.Clear();
            foreach (MagicStackItem mSI in stack)
                stackLB.Items.Add(mSI.ItemName);
            if (stack.Count != 0 && stack.Peek().GetType().Equals(typeof(MagicCard)))
                stackPB.Image = (Image)cardImages[stack.Peek().ItemName];
            else if (stack.Count != 0)
                stackPB.Image = MagicCove.Properties.Resources.magicCardBackSized;
            else
                stackPB.Image = null;
        }
        private void updateField()
        {
            p1FieldLB.Items.Clear();
            p2FieldLB.Items.Clear();
            foreach (MagicCard mc in p1Field.field)
            {
                if (mc.tapped)
                    p1FieldLB.Items.Add(mc.CardName + " (tapped)");
                else
                    p1FieldLB.Items.Add(mc.CardName);
            }
            foreach (MagicCard mc in p2Field.field)
            {
                if (mc.tapped)
                    p2FieldLB.Items.Add(mc.CardName + " (tapped)");
                else
                    p2FieldLB.Items.Add(mc.CardName);
            }
            //GUI for field updating is handled in move cards
        }
        private void updateGraveyard()
        {
            p1GraveyardLB.Items.Clear();
            p2GraveyardLB.Items.Clear();
            foreach (MagicCard mc in p1Field.graveyard)
            {
                p1GraveyardLB.Items.Add(mc.CardName);
            }
            foreach (MagicCard mc in p2Field.graveyard)
            {
                p2GraveyardLB.Items.Add(mc.CardName);
            }
            //update pic gui
            if (p1Field.graveyard.Count != 0)
                p1GraveyardPB.Image = getCardImage(p1Field.graveyard[p1Field.graveyard.Count - 1]); //last item to go in graveyard
            else
                p1GraveyardPB.Image = null;
            if (p2Field.graveyard.Count != 0)
                p2GraveyardPB.Image = getCardImage(p2Field.graveyard[p2Field.graveyard.Count - 1]); //last item to go in graveyard
            else
                p2GraveyardPB.Image = null;
        }
        private void updateExiled()
        {
            p1ExiledLB.Items.Clear();
            p2ExiledLB.Items.Clear();
            foreach (MagicCard mc in p1Field.exiled)
            {
                p1ExiledLB.Items.Add(mc.CardName);
            }
            foreach (MagicCard mc in p2Field.exiled)
            {
                p2ExiledLB.Items.Add(mc.CardName);
            }
            //update pic gui
            if (p1Field.exiled.Count != 0)
                p1ExiledPB.Image = getCardImage(p1Field.exiled[p1Field.exiled.Count - 1]);
            else
                p1ExiledPB.Image = null;
            if (p2Field.exiled.Count != 0)
                p2ExiledPB.Image = getCardImage(p2Field.exiled[p2Field.exiled.Count - 1]);
            else
                p2ExiledPB.Image = null;
        }
        private void updateAllDisplays()
        {
            updateHand(1);
            updateHand(2);
            updateStack();
            updateField();
            updateGraveyard();
            updateExiled();
        }
        private void updateTurnLabel()
        {
            pTurnL.Text = "Turn: " + turn.ToString() + "       Priority: " + priority.ToString();
        }
        private void updateLife()
        {
            p1LifeNUD.Value = p1Field.life;
            p2LifeNUD.Value = p2Field.life;
            p1PoisonNUD.Value = p1Field.PoisonCounters;
            p2PoisonNUD.Value = p2Field.PoisonCounters;
        }
        private void updateMana() //player 1 or 2, and mana contains the current floating mana.
        {
            p1ColorlessManaL.Text = "Colorless: " + p1Field.Mana[0];
            p1WhiteManaL.Text = "White:      " + p1Field.Mana[1];
            p1BlueManaL.Text = "Blue:        " + p1Field.Mana[2];
            p1BlackManaL.Text = "Black:      " + p1Field.Mana[3];
            p1RedManaL.Text = "Red:        " + p1Field.Mana[4];
            p1GreenManaL.Text = "Green:     " + p1Field.Mana[5];

            p2ColorlessManaL.Text = "Colorless: " + p2Field.Mana[0];
            p2WhiteManaL.Text = "White:      " + p2Field.Mana[1];
            p2BlueManaL.Text = "Blue:        " + p2Field.Mana[2];
            p2BlackManaL.Text = "Black:      " + p2Field.Mana[3];
            p2RedManaL.Text = "Red:        " + p2Field.Mana[4];
            p2GreenManaL.Text = "Green:     " + p2Field.Mana[5];
            
        }
        private void updatePhase()
        {//updates the phase of the game. (goes to the next phase)
            currentMessageL.Text = "Please enjoy Magic Cove presented to you by TechNaj";
            gamePhaseL.Font = new Font(gamePhaseL.Font.Name, 16, gamePhaseL.Font.Style, gamePhaseL.Font.Unit);
        IncrementPhase:
            phase++;
            phase = (Phase)((int)phase % 12);
            switch (phase)
            {
                case Phase.Untap:
                    turn = (Player)(((int)++turn) % numberOfPlayers);
                    if (turn == Player.P1)
                    {
                        p1Field.landPlayed = false;
                        foreach (MagicCard mC in p1Field.field)
                        {
                            mC.summoningSickness = false;
                            mC.tapped = false;
                        }
                    }
                    else
                    {
                        p2Field.landPlayed = false;
                        foreach (MagicCard mC in p2Field.field)
                        {
                            mC.summoningSickness = false;
                            mC.tapped = false;
                        }
                    }
                    gamePhaseL.Text = "Untap Step";
                    break;
                case Phase.Upkeep:
                    gamePhaseL.Text = "Upkeep Step";
                    break;
                case Phase.Draw:
                    gamePhaseL.Text = "Draw Step";
                    //draw card
                    if (turn == Player.P1)
                        p1Field.drawCard(0);
                    else
                        p2Field.drawCard(0);
                    break;
                case Phase.PreCombatMain:
                    gamePhaseL.Text = "First Main Step";
                    break;
                case Phase.BeginningOfCombat:
                    gamePhaseL.Font = new Font(gamePhaseL.Font.Name, 13, gamePhaseL.Font.Style, gamePhaseL.Font.Unit);
                    gamePhaseL.Text = "Beginning of Combat";
                    break;
                case Phase.DeclareAttackers:
                    currentMessageL.Text = "Please select attackers. (Press Declare Attackers).";
                    decTargetsB.Text = "Declare Attacker(s)";
                    gamePhaseL.Text = "Declare Attackers";
                    break;
                case Phase.DeclareBlockers: //~!~ flip priority? it is a turned based action so something else may have to be done
                    if (attackingCreatures.Count != 0) //illegal to declare defenders if there are no attackers
                    {
                        currentMessageL.Text = "Please select Blockers. (Press Declare Blockers).";
                        decTargetsB.Text = "Declare Blocker(s)";
                    }
                    gamePhaseL.Text = "Declare Blockers";
                    break;
                case Phase.CombatDamage://~!~ need to prompt somewhere how combat damage is distributed
                    gamePhaseL.Text = "Combat Damage";
                    performCombat();
                    break;
                case Phase.EndOfCombat:
                    gamePhaseL.Text = "End of Combat";
                    break;
                case Phase.PostCombatMain:
                    attackingCreatures = new List<MagicCard>();
                    defendingCreatures = new List<MagicCard>();
                    gamePhaseL.Font = new Font(gamePhaseL.Font.Name, 14, gamePhaseL.Font.Style, gamePhaseL.Font.Unit);
                    gamePhaseL.Text = "Second Main Step";
                    break;
                case Phase.End:
                    gamePhaseL.Text = "End Step";
                    break;
                case Phase.CleanUp:
                    gamePhaseL.Text = "Clean Up Step";
                    resetAllCreaturesAttackAndDefense();
                    break;
                default:
                    gamePhaseL.Font = new Font(gamePhaseL.Font.Name, 12, gamePhaseL.Font.Style, gamePhaseL.Font.Unit);
                    gamePhaseL.Text = "Illegal Game Phase";
                    break;
            }
            updateTurnLabel();
            activateAllSE();
            if (phase == Phase.Untap || phase == Phase.CleanUp)
                goto IncrementPhase;
            p1Field.Mana = new int[] { 0, 0, 0, 0, 0, 0 };
            p2Field.Mana = new int[] { 0, 0, 0, 0, 0, 0 };
            updateGame();
        }
        #endregion
        private void activateAllSE()
        {//triggers all sE.
            foreach (MagicCard card in p1Field.field)
                card.sE();
            foreach (MagicCard card in p2Field.field)
                card.sE();
            foreach (MagicCard card in p1Field.graveyard)
                card.sE();
            foreach (MagicCard card in p2Field.graveyard)
                card.sE();
            foreach (MagicCard card in p1Field.exiled)
                card.sE();
            foreach (MagicCard card in p2Field.exiled)
                card.sE();
        } //runs the sE for all cards on field or in graveyard
        #region Click Events
        private void playCardB_Click(object sender, EventArgs e) //slightly different than using an ability as card does not need to be tapped, however both are going to be combined here so change this text ~!~
        {//~!~ need to add support for multiple lands to be played at once
            MagicCard lastCardAttempted;
            List<MagicCard> selectedList = getAllSelectedCardsWithoutStack();
            bool manaTap = true; //if it was only mana that was tapped
            for (int i = 0; i < selectedList.Count; i++)
                if (selectedList[i].Location != CurrentLocation.Field || (selectedList[i].CardTypes & CardType.Land) == 0)
                {
                    manaTap = false;
                    break;
                }
            if (selectedList.Count == 0)
            {
                MessageBox.Show("Please select a card to play.");
                return;
            }
            else if (selectedList.Count > 1 && !manaTap)
            {
                MessageBox.Show("Please only play one card at a time. The only case you are allowed to select more than one card is to tap lands for mana (as mana abilities do not use the stack).", "ERROR - Multiple Cards Selected", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            else if ((selectedList[0].Owner == Player.P1 && priority != Player.P1) || (selectedList[0].Owner == Player.P2 && priority != Player.P2))
            {
                MessageBox.Show("Please select one of your own cards to play. If you are playing your own card then you currently do not have priority, the other player must pass you priority.", "Error - No Priority", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            else if (selectedList[0].Location == CurrentLocation.Hand) //play the card
            {
                lastCardAttempted = selectedList[0];
                lastCardAttempted.LocationGoing = CurrentLocation.Stack;
                lastCardAttempted.targets = new List<MagicCard>(currentTargets);
				activateAllSE();//mainly to allow cost reduction and incrementation to take place
                if (!lastCardAttempted.IsPlayable) //handles everything that must be done before placing a card on stack and determines if the card may go on stack
                {
                    lastCardAttempted.LocationGoing = CurrentLocation.Hand;
                    MessageBox.Show("That card cannot be played at this time. Please check that you have tapped the appropriate amount of mana and have read the cards description. (Note: Only Abilities and Instants may be activated during a non-main phase.)", "Error - Card Not Playable", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
                else
                {
                    activateAllSE();//note the card already says it is going to the stack
                    updateGame();
                }
            }
            else if (selectedList[0].SEAbilities.Count >= 1) //play the first ability.
            {
                while (selectedList.Count > 0)
                {//so that all mana abilities can be handled at once. (Normally we only execute this loop once). 
                    lastCardAttempted = selectedList[0];
                    stack.Push(lastCardAttempted.SEAbilities[0]); //pushed this early so manaAbilities can pop themselves and resolve
                    if (!(lastCardAttempted.Owner == Player.P1 && priority == Player.P1 && lastCardAttempted.SEAbilities[0].IsPlayable)
                        && !(lastCardAttempted.Owner == Player.P2 && priority == Player.P2 && lastCardAttempted.SEAbilities[0].IsPlayable))//if this is the case then card cannot be played
                    {
                        stack.Pop();
                        MessageBox.Show("You cannot activate the selected card's first ability at this time. Please read the cards description.", "Error - Card Cannot be Played", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                    else
                    {
                        activateAllSE();
                    }
                    selectedList.RemoveAt(0);
                }
            }
            else
                MessageBox.Show("That card has no first ability.", "Error - No First Ability", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            clearAllSelectedCard();
            updateGame();
        }

        private void p1ShowHideB_Click(object sender, EventArgs e)
        {
            if (p1Field.hand.Count > 0)//otherwise there is no point
                if (p1HandLB.FindStringExact("Card 1") == -1) //then it is being shown
                    updateHandWithCardBacks(1);
                else
                    updateHandWithCardImages(1);
        }
        private void p2ShowHideB_Click(object sender, EventArgs e)
        {
            if (p2Field.hand.Count > 0)//otherwise there is no point
                if (p2HandLB.FindStringExact("Card 1") == -1) //then it is being shown
                    updateHandWithCardBacks(2);
                else
                    updateHandWithCardImages(2);
        }
        private void resolveStackB_Click(object sender, EventArgs e)
        {
            List<MagicCard> tempSL = getAllSelectedCardsWithStack(); //can only be called once as it clears the selected cards
            if (enforceRules || (!enforceRules && tempSL.Count == 0))
            {
                priority = (Player)((int)(++priority) % numberOfPlayers);
                if (stack.Count == stackCountPrio)
                {
                    //resolve the top card (last element of list)
                    if (stack.Count > 0) //need to resolve top stack item
                    {
                        if (stack.Peek().GetType().Equals(typeof(MagicCard))) //then it is a magic card. should be called poppedStackItem function then and not have a bunch of this other stuff ~!~
                        {
                            if (stack.Peek().Countered || (((MagicCard)stack.Peek()).CardTypes & (CardType.Instant | CardType.Sorcery)) != 0)
                                ((MagicCard)stack.Peek()).LocationGoing = CurrentLocation.Graveyard;
                            else
                                ((MagicCard)stack.Peek()).LocationGoing = CurrentLocation.Field;
                            ((MagicCard)stack.Peek()).popedFromStack();
                        }
                        else //it is a sE that needs to be activated
                        {
                            if (stack.Peek().Countered)
                                stack.Pop();
                            else
                                stack.Pop().popedFromStack();
                        }
                        activateAllSE();
                        updateGame();
                    }
                    if (stackCountPrio == 0)
                        updatePhase();
                    stackCountPrio = -1; //reset the stack value (so guarenteed not the previous)
                    //Once stack resolves top card priority must be passed twice anyways so does not affect functionality.
                    priority = turn;//sets the priority back to player with turn
                }
                else
                {
                    stackCountPrio = stack.Count;
                }
            }
            else
            {//functionality need to be added to match description ~!~
                foreach (MagicCard mC in tempSL)
                    mC.LocationGoing = CurrentLocation.Field;
                updateGame();
                if (sender is PictureBox) //set location to where it was dragged if a pb was dragged
                    if (tempSL[0].Owner == Player.P1)
                        p1FieldPBs[p1FieldPBs.Count - 1].Location = ((PictureBox)sender).Location;
                    else
                        p2FieldPBs[p2FieldPBs.Count - 1].Location = ((PictureBox)sender).Location;
            }
            updateTurnLabel();
        }
        private void decTargetsB_Click(object sender, EventArgs e)
        {
            currentTargets = getAllSelectedCardsWithoutStack();
        }
        private void decAttackersB_Click(object sender, EventArgs e)
        {
            if (enforceRules)
            {
                attackingCreatures = getAllSelectedCardsWithoutStack();
                foreach (MagicCard mC in attackingCreatures) //check if valid cards selected
                    if (mC.tapped || (mC.CardTypes & CardType.Creature) == 0 || mC.summoningSickness || (mC.Owner == Player.P1 && turn != Player.P1) || (mC.Owner == Player.P2 && turn != Player.P2) || mC.Location != CurrentLocation.Field)
                    {
                        MessageBox.Show("You selected something that isn't unable to attack or is not a creature (or not your card). Please try again.");
                        attackingCreatures = new List<MagicCard>();
                        return;
                    }
                foreach (MagicCard mCA in attackingCreatures)
                    mCA.tapped = true;
                activateAllSE(); //cards with special requirements can now remove themselves from the list or prompt the player to action (also vigilance can untap)
                updateGame();
                currentMessageL.Text = "For each attacking creature please select a target player. ";
                string playerName = "oponent player";
                foreach (MagicCard mC in attackingCreatures)
                {
                    mC.combatTarget = null; //null indicates that it is the player to be attacked (may need to be changed)
                    while (MessageBox.Show("Should " + mC.CardName + " attack " + playerName + "?", "Player Selection Dialog", MessageBoxButtons.YesNo).Equals(DialogResult.No))
                    {
                        mC.combatTarget = null;
                        playerName = "~!~ Implementation here needs to be changed to support planeswalkers"; //(planeswalkers will be located in p#field.additionalPlayers
                    }
                }
                //~!~ some fancy stuff about count being greater and legality check.
                //pay for cost of attack (probably included in implementation above)
                //user can now play abilities
                currentMessageL.Text = "Please enjoy Magic Cove presented to you by TechNaj";
            }
            else
            {
                List<MagicCard> mCL = getAllSelectedCardsWithoutStack();
                foreach (MagicCard mC in mCL)
                    mC.LocationGoing = CurrentLocation.Field;
            }
        }
        private void decDefendersB_Click(object sender, EventArgs e)
        {
            if (enforceRules)
            {
                defendingCreatures = getAllSelectedCardsWithoutStack();
                if (attackingCreatures.Count == 0)
                {
                    MessageBox.Show("Oponent is not attacking with any creatures. Play continues.");
                    return;
                }
                foreach (MagicCard mC in defendingCreatures)
                    if (mC.tapped || (mC.CardTypes & CardType.Creature) == 0 || mC.Owner == turn || mC.Location != CurrentLocation.Field)
                    {
                        MessageBox.Show("You selected something that isn't unable to defend as it is tapped or is not a creature (or not your card). Please try again.");
                        defendingCreatures = new List<MagicCard>();
                        return;
                    }
                activateAllSE(); //cards with special requirements can now remove themselves from the list or prompt the player to action
                currentMessageL.Text = "For each defending creature please select a creature to black. ";
                foreach (MagicCard mC in defendingCreatures)
                {
                    mC.combatTarget = null; //null indicates that it is the player to be attacked (may need to be changed)
                    foreach (MagicCard mCA in attackingCreatures)
                    {
                        if (MessageBox.Show("Should " + mC.CardName + " block " + mCA.CardName + "?", "Player Selection Dialog--~!~More Intuitive interface coming soon", MessageBoxButtons.YesNo).Equals(DialogResult.Yes))
                        {
                            mC.combatTarget = mCA;
                            break;
                        }
                    }
                    if (mC.combatTarget == null)
                    {
                        MessageBox.Show("Error: You did not select something to block. Please try again.", "Blocker Selection Failed");
                        defendingCreatures = null;
                        return;
                    }
                }
                //~!~ some fancy stuff about count being greater and legality check.
                //pay for cost of attack (probably included in implementation above)
                //user can now play abilities
                currentMessageL.Text = "Please enjoy Magic Cove presented to you by TechNaj";
            }
            else
            {
                List<MagicCard> mCList = getAllSelectedCardsWithStack();
                foreach (MagicCard mC in mCList)
                    mC.LocationGoing = CurrentLocation.Hand;
            }
            updateGame();
        }

        private void useAbility2B_Click(object sender, EventArgs e)
        {
            ;
        }
        private void useAbility3B_Click(object sender, EventArgs e)
        {
            if (enforceRules)
                ;
            else
            {
                List<MagicCard> mCList = getAllSelectedCardsWithStack();
                foreach (MagicCard mC in mCList)
                    mC.LocationGoing = CurrentLocation.Graveyard;
            }
            updateGame();
        }
        private void useAbility4B_Click(object sender, EventArgs e)
        {
            if (enforceRules)
                ;
            else
            {
                List<MagicCard> mCList = getAllSelectedCardsWithStack();
                foreach (MagicCard mC in mCList)
                    mC.LocationGoing = CurrentLocation.Exiled;
            }
            updateGame();
        }

        private void getCardInfoB_Click(object sender, EventArgs e)
        {//Currently this button gets the information about the selected card
            //make message box get info like it is suppose too ~!~
            List<MagicCard> mCList = getAllSelectedCardsWithoutStack();
            if (mCList.Count == 0)
                MessageBox.Show("Please select a card to get the information about.", "Error - No Card Selected");
            else if (mCList.Count > 1)
                MessageBox.Show("Please only select one card to the information about.", "Error - Multiple Cards Selected");
            else
            {
                //make a string out of the lists
                String manaCostS = "";
                String sES = "";
                String sEIpS = "";
                if (mCList[0].ManaCost != null)
                    foreach (ManaType mT in mCList[0].ManaCost)
                        manaCostS += mT.ToString() + ", ";
                foreach (sEBase sE in mCList[0].SEAbilities)
                    sES += sE.ToString() + ", ";
                foreach (sEBase sE in mCList[0].SEAbilities)
                    sEIpS += sE.IPClass.ToString() + ", ";
                //remove trailing comma and space
                if (manaCostS.Length > 2)
                    manaCostS = manaCostS.Substring(0, manaCostS.Length - 2);
                else
                    manaCostS = "None";
                if (sES.Length > 2)
                    sES = sES.Substring(0, sES.Length - 2);
                else
                    sES = "None";
                if (sEIpS.Length > 2)
                    sEIpS = sEIpS.Substring(0, sEIpS.Length - 2);
                else
                    sEIpS = "None";
                //display info
                MessageBox.Show("Card Name: " + mCList[0].CardName +
                    "\nMana Cost: " + manaCostS +
                    "\nCard Type: " + mCList[0].CardTypes.ToString() +
                    "\nAttack: " + mCList[0].Attack.ToString() +
                    "   (Current Attack: " + mCList[0].TempAttack.ToString() + ")" +
                    "\nDefense: " + mCList[0].Defense.ToString() +
                    "   (Current Defense: " + mCList[0].TempDefense.ToString() + ")" +
                    "\nPlus One Counters: " + mCList[0].PlusOneCounters +
                    "\nMinus One Counters: " + mCList[0].MinusOneCounters +
                    "\nTapped: " + mCList[0].tapped.ToString() +
                    "\nSummoning Sickness: " + mCList[0].summoningSickness.ToString() +
                    "\nCountered: " + mCList[0].Countered.ToString() +
                    "\nLocation: " + mCList[0].Location.ToString() +
                    "\nLocation Going: " + mCList[0].LocationGoing.ToString() +
                    "\nPlayability Condition: " + mCList[0].IPClass.ToString() +
                    "\nSpecial Effect Abilities: " + sES +
                    "\nCorresponding IPs for SEs: " + sEIpS +
                    "\nOwner: " + mCList[0].Owner +
                    "\n\n\nWould you like to see the card rulings? (It may take a while).", "Selected Card's Information - " + mCList[0].CardName, MessageBoxButtons.YesNoCancel);
            }
        }
        private void endTurnB_Click(object sender, EventArgs e)
        {
            if (stack.Count != 0)
            {
                MessageBox.Show("Error: Stack is not empty, please resolve stack before ending turn.");
                return;
            }
            if (endTurnB.Text.Equals("End Turn?"))
                endTurnB.Text = "Accept End Turn?";
            else
            {
                //always do this at least once 
                Player tempTurn = turn;
                while (tempTurn == turn)
                {
                    updatePhase();
                }
                priority = turn;
                endTurnB.Text = "End Turn?";
            }
        }
        #endregion
        #region Mouse Handler and Support Functions
        private void p1HandPB_MouseEnter(object sender, EventArgs e)
        {
            PictureBox pB = (PictureBox)sender;
            if (p1HandPBs.IndexOf(pB) != 0
                && p1HandPBs[p1HandPBs.IndexOf(pB) - 1].Location.X < pB.Location.X - pB.Size.Width) //special effect case
            {
                pB.Location = new System.Drawing.Point(pB.Location.X - (MAGNIFICATION_MULTIPLIER - 1) * pB.Size.Width, pB.Location.Y - (MAGNIFICATION_MULTIPLIER - 1) * pB.Size.Height);
            }
            else
            {
                pB.Location = new System.Drawing.Point(pB.Location.X, pB.Location.Y - (MAGNIFICATION_MULTIPLIER - 1) * pB.Size.Height);
                handShiftCardsRight(Player.P1, p1HandPBs.IndexOf(pB));
            }
            pB.Size = new System.Drawing.Size(pB.Size.Width * MAGNIFICATION_MULTIPLIER, pB.Size.Height * MAGNIFICATION_MULTIPLIER);
            pB.BringToFront();
        }
        private void p1HandPB_MouseLeave(object sender, EventArgs e)
        {
            PictureBox pB = (PictureBox)sender;
            pB.Size = new System.Drawing.Size(pB.Size.Width / MAGNIFICATION_MULTIPLIER, pB.Size.Height / MAGNIFICATION_MULTIPLIER);
            pB.Location = new System.Drawing.Point(pB.Location.X, pB.Location.Y + (MAGNIFICATION_MULTIPLIER - 1) * pB.Size.Height);
            if (!(PointToClient(MousePosition).X >= getLocationRelativeToForm(pB).X + (MAGNIFICATION_MULTIPLIER) * pB.Size.Width 
                && PointToClient(MousePosition).Y >= getLocationRelativeToForm(pB).Y && PointToClient(MousePosition).Y <= getLocationRelativeToForm(pB).Y + pB.Size.Height
                && p1HandPBs.IndexOf(pB) != p1HandPBs.Count - 1)) //not mouse move off to right, do not do a special effect. (and make sure it is not the last card)
            {
                handShiftCardsLeft(Player.P1, p1HandPBs.IndexOf(pB));
                //refresh and z order
                foreach (PictureBox pBEl in p1HandPBs)
                    pBEl.BringToFront();
            }
        }
        private void p2HandPB_MouseEnter(object sender, EventArgs e)
        {
            PictureBox pB = (PictureBox)sender;
            if (p2HandPBs.IndexOf(pB) != 0
                && p2HandPBs[p2HandPBs.IndexOf(pB) - 1].Location.X < pB.Location.X - pB.Size.Width) //special effect case
            {
                pB.Location = new System.Drawing.Point(pB.Location.X - (MAGNIFICATION_MULTIPLIER - 1) * pB.Size.Width, pB.Location.Y);
            }
            else
            {
                handShiftCardsRight(Player.P2, p2HandPBs.IndexOf(pB));
            }
            pB.Size = new System.Drawing.Size(pB.Size.Width * MAGNIFICATION_MULTIPLIER, pB.Size.Height * MAGNIFICATION_MULTIPLIER);
            pB.BringToFront();
        }
        private void p2HandPB_MouseLeave(object sender, EventArgs e)
        {//Check where the mouse is leaving to to see if you have to do a special effect
            PictureBox pB = (PictureBox)sender;
            pB.Size = new System.Drawing.Size(pB.Size.Width / MAGNIFICATION_MULTIPLIER, pB.Size.Height / MAGNIFICATION_MULTIPLIER);
            if (!(PointToClient(MousePosition).X >= getLocationRelativeToForm(pB).X + (MAGNIFICATION_MULTIPLIER) * pB.Size.Width
                && PointToClient(MousePosition).Y >= getLocationRelativeToForm(pB).Y && PointToClient(MousePosition).Y <= getLocationRelativeToForm(pB).Y + pB.Size.Height
                && p2HandPBs.IndexOf(pB) != p2HandPBs.Count - 1)) //not mouse move off to right, do not do a special effect. (and make sure it is not the last card)
            {
                handShiftCardsLeft(Player.P2, p2HandPBs.IndexOf(pB));
                //refresh and z order
                foreach (PictureBox pBEl in p2HandPBs)
                    pBEl.BringToFront();
            }
        }
        private void handShiftCardsRight(Player player, int index) //the index of card that is being enlarged (+1=first card to move)
        {
            index++;
            if (player == Player.P1)
                while (index < p1HandPBs.Count)
                {
                    p1HandPBs[index].Location = new System.Drawing.Point(p1HandPBs[index].Location.X + (MAGNIFICATION_MULTIPLIER - 1) * p1HandPBs[index].Size.Width, p1HandPBs[index].Location.Y);
                    index++;
                }
            else
                while (index < p2HandPBs.Count)
                {
                    p2HandPBs[index].Location = new System.Drawing.Point(p2HandPBs[index].Location.X + (MAGNIFICATION_MULTIPLIER - 1) * p2HandPBs[index].Size.Width, p2HandPBs[index].Location.Y);
                    index++;
                }
        }
        private void handShiftCardsLeft(Player player, int index)
        {
            index++;
            if (player == Player.P1)
                while (index < p1HandPBs.Count)
                {
                    p1HandPBs[index].Location = new System.Drawing.Point(p1HandPBs[index].Location.X - (MAGNIFICATION_MULTIPLIER - 1) * p1HandPBs[index].Size.Width, p1HandPBs[index].Location.Y);
                    index++;
                }
            else
                while (index < p2HandPBs.Count)
                {
                    p2HandPBs[index].Location = new System.Drawing.Point(p2HandPBs[index].Location.X - (MAGNIFICATION_MULTIPLIER - 1) * p2HandPBs[index].Size.Width, p2HandPBs[index].Location.Y);
                    index++;
                }
        }
        private Point getLocationRelativeToForm(Control c)
        {
            if (c.Parent.GetType().Equals(typeof(GameForm)))
                return c.Location;
            else
                return new Point(c.Location.X + getLocationRelativeToForm(c.Parent).X, c.Location.Y + getLocationRelativeToForm(c.Parent).Y);
        }
        private void p1HandPB_DoubleClick(object sender, EventArgs e)
        {
            isDragging = false;
            p1HandLB.SelectedIndex = p1HandPBs.IndexOf((PictureBox)sender);
            playCardB_Click(sender, e);
        }
        private void p2HandPB_DoubleClick(object sender, EventArgs e)
        {
            isDragging = false;
            p2HandLB.SelectedIndex = p2HandPBs.IndexOf((PictureBox)sender);
            playCardB_Click(sender, e);
        }
        private void stackPB_DoubleClick(object sender, EventArgs e)
        {
            if (stack.Count != 0)
            {
                stackLB.SelectedIndex = 0;
                resolveStackB_Click(sender, e);
            }
        }
        private void p1DeckPB_DoubleClick(object sender, EventArgs e)
        {
            p1Field.drawCard();
            if (p1Field.deck.Count == 0)
                p1DeckPB.Image = null;
            updateHand(1);
        }
        private void p2DeckPB_DoubleClick(object sender, EventArgs e)
        {
            p2Field.drawCard();
            if (p2Field.deck.Count == 0)
                p2DeckPB.Image = null;
            updateHand(2);
        }

        private void p1FieldPB_MouseEnter(object sender, EventArgs e)
        {//magnifies the box and brings to front
            PictureBox pB = (PictureBox)sender;
            pB.Size = new System.Drawing.Size(pB.Size.Width * MAGNIFICATION_MULTIPLIER, pB.Size.Height * MAGNIFICATION_MULTIPLIER);
            pB.BringToFront();
        }
        private void p1FieldPB_MouseLeave(object sender, EventArgs e)
        {
            PictureBox pB = (PictureBox)sender;
            pB.Size = new System.Drawing.Size(pB.Size.Width / MAGNIFICATION_MULTIPLIER, pB.Size.Height / MAGNIFICATION_MULTIPLIER);
        }
        private void p2FieldPB_MouseEnter(object sender, EventArgs e)
        {//magnifies the box, shifts it and brings to front
            PictureBox pB = (PictureBox)sender;
            pB.Location = new Point(pB.Location.X, pB.Location.Y - (MAGNIFICATION_MULTIPLIER - 1) * pB.Size.Height);
            pB.Size = new System.Drawing.Size(pB.Size.Width * MAGNIFICATION_MULTIPLIER, pB.Size.Height * MAGNIFICATION_MULTIPLIER);
            pB.BringToFront();
        }
        private void p2FieldPB_MouseLeave(object sender, EventArgs e)
        {
            PictureBox pB = (PictureBox)sender;
            pB.Size = new System.Drawing.Size(pB.Size.Width / MAGNIFICATION_MULTIPLIER, pB.Size.Height / MAGNIFICATION_MULTIPLIER);
            pB.Location = new Point(pB.Location.X, pB.Location.Y + (MAGNIFICATION_MULTIPLIER - 1) * pB.Size.Height);
        }
        private bool isDragging = false;
        private int prevMouseX;
        private int prevMouseY;
        private Point originalLocation;
        private void GUIPBDrag_MouseDown(object sender, MouseEventArgs e)
        {
            if (sender is PictureBox && e.Button == MouseButtons.Left)
            {
                prevMouseX = e.X;
                prevMouseY = e.Y;
                originalLocation = new Point(((PictureBox)sender).Location.X, ((PictureBox)sender).Location.Y); //can't just copy reference, as value may change (in current implementation it does not)
                isDragging = true;
            }
        }
        private void GUIPBDrag_MouseMove(object sender, MouseEventArgs e)
        {
            if (isDragging)
            {
                PictureBox pB = (PictureBox)sender;
                pB.Location = new System.Drawing.Point(pB.Location.X + e.X - prevMouseX, pB.Location.Y + e.Y - prevMouseY);
            }
        }
        private void GUIPBDrag_MouseUp(object sender, MouseEventArgs e)
        {
            if (isDragging)
            {
                isDragging = false;
                if (sender is PictureBox && e.Button == MouseButtons.Left && ((PictureBox)sender).Location.X != originalLocation.X && ((PictureBox)sender).Location.Y != originalLocation.Y)//if it has not moved, give a chance to double click to trigger
                {//assumes only one picture box can be dragged at a time (which should always be the case)
                    PictureBox pB = (PictureBox)sender;
                    bool notFieldItem = !(p1FieldPBs.Contains(pB) || p2FieldPBs.Contains(pB));//if it is not a picture box field, restore the image to its orginal location. field pB will either be move around the field, or if transfered to a different location, deleted
                    //select the card the is being dragged (everything else will set selected index to -1 which is fine)
                    p1HandLB.SelectedIndex = p1HandPBs.IndexOf(pB);
                    p2HandLB.SelectedIndex = p2HandPBs.IndexOf(pB);
                    p1FieldLB.SelectedIndex = p1FieldPBs.IndexOf(pB);
                    p2FieldLB.SelectedIndex = p2FieldPBs.IndexOf(pB);
                    if (pB == p1GraveyardPB)
                        p1GraveyardLB.SelectedIndex = p1GraveyardLB.Items.Count - 1;
                    if (pB == p2GraveyardPB)
                        p2GraveyardLB.SelectedIndex = p2GraveyardLB.Items.Count - 1;
                    if (pB == p1ExiledPB)
                        p1ExiledLB.SelectedIndex = p1ExiledLB.Items.Count - 1;
                    if (pB == p2ExiledPB)
                        p2ExiledLB.SelectedIndex = p2ExiledLB.Items.Count - 1;
                    //call function to send it to the appropriate place.
                    if (p1HandPBs.Contains(pB) || p1FieldPBs.Contains(pB) || pB == p1GraveyardPB || pB == p1ExiledPB) //p1 cases
                    {
                        if (!(p1HandPBs.Contains(pB)) && e.X + pB.Location.X < p1FieldDividerL.Location.X + p1FieldDividerL.Size.Width && e.Y + pB.Location.Y > p1FieldDividerL.Location.Y)
                            decDefendersB_Click(sender, e);
                        else if (!(pB == p1GraveyardPB) && e.X + pB.Location.X > p1GraveyardPB.Location.X && e.Y + pB.Location.Y > p1GraveyardPB.Location.Y && e.Y + pB.Location.Y < p1GraveyardPB.Location.Y + p1GraveyardPB.Size.Height)
                            useAbility3B_Click(sender, e);
                        else if (!(pB == p1ExiledPB) && e.X + pB.Location.X > p1ExiledPB.Location.X && e.Y + pB.Location.Y > p1ExiledPB.Location.Y && e.Y + pB.Location.Y < p1ExiledPB.Location.Y + p1ExiledPB.Size.Height)
                            useAbility4B_Click(sender, e);
                        else if (!p1FieldPBs.Contains(pB) && e.X + pB.Location.X < p1FieldDividerL.Location.X + p1FieldDividerL.Size.Width && e.Y + pB.Location.Y < p1FieldDividerL.Location.Y)
                            resolveStackB_Click(sender, e);
                    }
                    else //p2 cases
                    {
                        if (!(p2HandPBs.Contains(pB)) && e.X + pB.Location.X < p2FieldDividerL.Location.X + p2FieldDividerL.Size.Width && e.Y + pB.Location.Y < p2FieldDividerL.Location.Y)
                            decDefendersB_Click(sender, e);
                        else if (!(pB == p2GraveyardPB) && e.X + pB.Location.X > p2GraveyardPB.Location.X && e.Y + pB.Location.Y > p2GraveyardPB.Location.Y && e.Y + pB.Location.Y < p2GraveyardPB.Location.Y + p2GraveyardPB.Size.Height)
                            useAbility3B_Click(sender, e);
                        else if (!(pB == p2ExiledPB) && e.X + pB.Location.X > p2ExiledPB.Location.X && e.Y + pB.Location.Y > p2ExiledPB.Location.Y && e.Y + pB.Location.Y < p2ExiledPB.Location.Y + p2ExiledPB.Size.Height)
                            useAbility4B_Click(sender, e);
                        else if (!p2FieldPBs.Contains(pB) && e.X + pB.Location.X < p2FieldDividerL.Location.X + p2FieldDividerL.Size.Width && e.Y + pB.Location.Y > p2FieldDividerL.Location.Y)
                            resolveStackB_Click(sender, e);
                    }
                    if (notFieldItem) //then pB still exists after being moved
                        pB.Location = originalLocation;
                }
            }
        }
        private void fieldPB_MouseDoubleClick(object sender, MouseEventArgs e)
        {//tap or untap the card
            isDragging = false;
            PictureBox pB = (PictureBox)sender;
            if (pB.Size.Height > pB.Size.Width) //has not be rotated yet
                pB.Image.RotateFlip(RotateFlipType.Rotate90FlipNone);
            else
                pB.Image.RotateFlip(RotateFlipType.Rotate270FlipNone);
            pB.Size = new Size(pB.Size.Height, pB.Size.Width);
            if (p1FieldPBs.IndexOf(pB) != -1)
                p1Field.field[p1FieldPBs.IndexOf(pB)].tapped = !p1Field.field[p1FieldPBs.IndexOf(pB)].tapped;
            else
                p2Field.field[p2FieldPBs.IndexOf(pB)].tapped = !p2Field.field[p2FieldPBs.IndexOf(pB)].tapped;
            updateAllDisplays();
        }
        private void p1GraveyardPB_MouseEnter(object sender, EventArgs e)
        {
            p1GraveyardGUIL.Text = "Grave-\nyard\n(" + p1Field.graveyard.Count + ")";
            p1GraveyardGUIL.Visible = true;
        }
        private void p1GraveyardPB_MouseLeave(object sender, EventArgs e)
        {
            p1GraveyardGUIL.Visible = false;
        }
        private void p2GraveyardPB_MouseEnter(object sender, EventArgs e)
        {
            p2GraveyardGUIL.Text = "Grave-\nyard\n(" + p2Field.graveyard.Count + ")";
            p2GraveyardGUIL.Visible = true;
        }
        private void p2GraveyardPB_MouseLeave(object sender, EventArgs e)
        {
            p2GraveyardGUIL.Visible = false;
        }
        private void p1GraveyardPB_DoubleClick(object sender, EventArgs e)
        {
            if (p1Field.graveyard.Count != 0)
            {
                p1GraveyardLB.SelectedIndex = p1Field.graveyard.Count - 1;
                resolveStackB_Click(sender, e);
            }
        }
        private void p2GraveyardPB_DoubleClick(object sender, EventArgs e)
        {
            if (p2Field.graveyard.Count != 0)
            {
                p2GraveyardLB.SelectedIndex = p2Field.graveyard.Count - 1;
                resolveStackB_Click(sender, e);
            }
        }
        #endregion
        #region Tool Strip Events
        private void hideLeftControlsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //~!~ Need to change this so that phase game stats are move onto the screen
            if (this.playingField00SC.Panel1Collapsed)
            {
                this.playingField00SC.Panel1Collapsed = false;
                this.hideLeftControlsToolStripMenuItem.Text = "Hide Left Controls";
            }
            else
            {
                this.playingField00SC.Panel1Collapsed = true;
                this.hideLeftControlsToolStripMenuItem.Text = "Show Left Controls";
            }
        }
        private void optionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OptionsForm tempOF = new OptionsForm();
            tempOF.ShowDialog();
        }
        #endregion

        #region Constants
        private const int MAGNIFICATION_MULTIPLIER = 3;
        #endregion

        private void helpToolStripMenuItem_Click(object sender, EventArgs e)
        {
            System.Threading.Thread HThread = new System.Threading.Thread(new System.Threading.ThreadStart(Program.newHelpThread));
            HThread.Start();
        }
    }

    interface MagicStackItem
    {
        String ItemName
        {
            get;
        }
        bool Countered
        {
            get;
            set;
        }
        bool IsPlayable //returns whether the item is playable
        {
            get;
        }
        iPBase IPClass //returns the class is Playable that the Item contains
        {
            get;
        }
        void popedFromStack();//called after the item has been poped from the stack
    }
}
